package cn.tedu.basic;
//测试JDBC
//测试 SQL 注入攻击问题
//注意：有SQL注入攻击的现象，改变了SQL的语义；
//解决办法：完成SQL的拼接；接收用户输入的用户名和密码，动态的拼接SQL
//中文乱码:
//

import com.mysql.jdbc.jdbc2.optional.MysqlXid;

import java.io.Closeable;
import java.sql.*;
import java.util.Scanner;

public class TestJdbc {
    public static void main(String[] args) throws Exception {
//        method();//普通方式
//        method2();//暴露SQL注入问题
//        method3();//解决SQL注入问题
        method4();//创建JdbcUtils工具类，优化改造原来的代码。
    }

    private static void method4()  {
        //1./2.TODO 改造：调用工具类，获取和数据库的连接
        Connection con = null;
        PreparedStatement ps=null;
        ResultSet rs =null;
        try {
            con = JdbcUtils.getConnection();

        //3.获取传输器
            //?叫做占位符,PreparedStatement只把SQL骨架发送给数据库;
        String sql = "select * from user where name=? and pwd=?";
        ps = con.prepareStatement(sql);
        ps.setString(1, "jack");
        ps.setString(2, "123");
        //4.执行SQL语句
             rs = ps.executeQuery();
        //5.解析结果集
        while(rs.next()){//next()判断有数据吗?有数据就一个一个解析id/name/pwd
            for (int i = 1; i < 4; i++) {
                System.out.println(rs.getString(i));//按索引查
            }
        }
        //6.释放资源，一定要被执行！！！！
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
                CloseableUtils.close(rs,ps,con);
        }
    }

    private static void method3() throws Exception {
        //1.注册驱动jar包
        Class.forName("com.mysql.jdbc.Driver");

        //2.连接数据库
        //?characterEcoding=utf8-----设置数据库可以识别中文字符集
        String url="jdbc:mysql:///jdbctest?characterEcoding=utf8";
        String name="root";
        String pwd="root";
        Connection con = DriverManager.getConnection(url, name, pwd);

        //3.获取传输器
        String sql = "select * from user where name=? and pwd=?";
        PreparedStatement ps = con.prepareStatement(sql);
        ps.setString(1, "jack");
        ps.setString(2, "123");
        //4.执行SQL语句
        ResultSet rs = ps.executeQuery(sql);
        //5.解析结果集
        while(rs.next()){//next()判断有数据吗?有数据就一个一个解析id/name/pwd
            for (int i = 0; i < 4; i++) {
                System.out.println(rs.getString(i));//按索引查
            }
        }
        //6.释放资源
        rs.close();
        ps.close();
        con.close();

    }

    private static void method2() throws Exception {
        //1.注册驱动jar包
        Class.forName("com.mysql.jdbc.Driver");
        //2.连接数据库
        //getConnection(1,2,3)--1是哪个数据库,2是用户名,3是密码
        Connection con=DriverManager.getConnection(
//                "协议://服务器的名字:数据库的端口号/数据库库名","用户名","密码");
                "jdbc:mysql://localhost:3306/jdbctest","root","root");
        //此处如果是使用的本机的服务器,并且是默认的端口3306,就可以将其省略--"jdbc:mysql:///jdbctest","root","root");
        //3.获取传输器
        Statement st = con.createStatement();

        //4.执行SQL
        //TODO 测试SQL注入攻击问题---jack'#    jack 'or' 1=1
        //注入攻击是指当用户输入数据时，恶意包含了特殊的SQL语句，改变了SQL语义；
        //导致只需要名字，不需要输入密码也可以查看所有数据（数据泄露）
        //名字输入后面两种值，都会产生SQL攻击问题：jack'#    jack 'or' 1=1
        String a= new Scanner(System.in).nextLine();
        String b= new Scanner(System.in).nextLine();
        String sql="select * from user where name='"+a+"'and pwd='"+b+"'";// TODO 这里必须要拼接，要保持a/b为变量；
        ResultSet rs = st.executeQuery(sql);

        //5.解析结果集
        while(rs.next()){//next()判断有数据吗?有数据就一个一个解析id/name/pwd
            for (int i = 0; i < 4; i++) {
                System.out.println(rs.getString(i));//按索引查

            }
        }
        //6.释放资源
        rs.close();
        st.close();
        con.close();



    }

    //使用JDBC查询 user 表的数据
    private static void method() throws Exception {
        //1.注册驱动jar包
        Class.forName("com.mysql.jdbc.Driver");
        //2.连接数据库
        //getConnection(1,2,3)--1是哪个数据库,2是用户名,3是密码
        Connection con=DriverManager.getConnection(
//                "协议://服务器的名字:数据库的端口号/数据库库名","用户名","密码");
                "jdbc:mysql://localhost:3306/jdbctest","root","root");
                //此处如果是使用的本机的服务器,并且是默认的端口3306,就可以将其省略--"jdbc:mysql:///jdbctest","root","root");
        //3.获取传输器
        Statement st = con.createStatement();

        //TODO 测试SQL注入攻击问题---jack'#    jack 'or' 1=1
        //注入攻击是指当用户输入数据时，恶意包含了特殊的SQL语句，改变了SQL语义；
        //导致只需要名字，不需要输入密码也可以查看所有数据（数据泄露）
        //名字输入后面两种值，都会产生SQL攻击问题：jack'#    jack 'or' 1=1
        String a= new Scanner(System.in).nextLine();
        String b= new Scanner(System.in).nextLine();
        String sql="select * from user where name='"+a+"'and pwd='"+b+"'";

        //4.执行SQL
        String sql2="SELECT * FROM USER WHERE NAME='jack' AND pwd=123; ";
        ResultSet rs = st.executeQuery(sql);
        //5.解析结果集
        while(rs.next()){//next()判断有数据吗?有数据就一个一个解析id/name/pwd
            for (int i = 0; i < 4; i++) {
                System.out.println(rs.getString(i));//按索引查

            }
        }
        //6.释放资源
        rs.close();
        st.close();
        con.close();
    }

}


